package za.org.jcicada.comms.impl.udp;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.nio.channels.DatagramChannel;

import za.org.jcicada.comms.IConnection;
import za.org.jcicada.comms.IConnector;

public class UdpConnector implements IConnector {
	
	private final SocketAddress target;
	private final SocketAddress local;

	public UdpConnector(String host, int port) {
		this(new InetSocketAddress(host, port));
	}
	
	public UdpConnector(URI locationURI) {
		this(locationURI.getHost(), locationURI.getPort());
		if (!locationURI.getScheme().equals(UdpAcceptor.UDP)) {
			throw new IllegalArgumentException(String.format("Scheme must be '%s' but was '%s'", UdpAcceptor.UDP, locationURI.getScheme()));
		}
	}
	
	public UdpConnector(SocketAddress target) {
		this(target, new InetSocketAddress(0));	// port 0 selects any available port
	}
	
	public UdpConnector(SocketAddress target, SocketAddress local) {
		this.target = target;
		this.local = local;
	}
	
	public SocketAddress getTarget() {
		return target;
	}

	@Override
	public IConnection connect() throws IOException {
	    DatagramChannel channel = DatagramChannel.open();
	    channel.configureBlocking(false);
		DatagramSocket socket = channel.socket();
		socket.setReuseAddress(true);
		socket.bind(local);
		channel.connect(target);
		IConnection connection = createConnection(channel);
		return connection;
	}
	
	protected IConnection createConnection(DatagramChannel channel) {
		return new UdpConnection(channel);
	}
	
}
